package com.feityz.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feityz.system.dao.RoleAreaMapper;
import com.feityz.system.entity.Role;
import com.feityz.system.entity.RoleArea;
import com.feityz.system.entity.RoleAreaUser;
import com.feityz.system.entity.User;
import com.feityz.system.input.GetAreaByUserInput;
import com.feityz.system.input.RoleAreaInput;
import com.feityz.system.input.RoleAreaQueryInput;
import com.feityz.system.service.IRoleAreaService;
import com.feityz.system.service.IRoleAreaUserService;
import com.feityz.system.service.IRoleService;
import com.feityz.system.service.IUserService;
import com.feityz.system.vo.RoleAreaUserVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleAreaServiceImpl extends ServiceImpl<RoleAreaMapper, RoleArea> implements IRoleAreaService {

    private static String ROLE_NAME = "HQZG";
    @Autowired
    private IRoleAreaUserService roleAreaUserService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IUserService userService;
    @Override
    @Transactional
    public void saveRelation(RoleAreaInput input){
        Assert.isTrue(input.getArea()!=null,"请传入辖区字段");
        Assert.isTrue(input.getRoleId()!=null,"请传入角色字段");
        Assert.isTrue(CollectionUtil.isNotEmpty(input.getUserId()),"请传入人员");

        RoleArea roleArea = new RoleArea();
        roleArea.setArea(input.getArea());
        roleArea.setRoleId(input.getRoleId());
        if(input.getId()==null) {
            //查找重复的
            //新增
            List<RoleArea> list = lambdaQuery().eq(RoleArea::getArea, input.getArea())
                    .eq(RoleArea::getRoleId, input.getRoleId())
                    .list();
            Assert.isTrue(CollectionUtil.isEmpty(list),"重复数据");
            this.save(roleArea);
        }else{
            roleArea.setId(input.getId());
            //修改
            List<RoleArea> list = lambdaQuery().eq(RoleArea::getArea, input.getArea())
                    .ne(RoleArea::getId,input.getId())
                    .eq(RoleArea::getRoleId, input.getRoleId())
                    .list();
            Assert.isTrue(CollectionUtil.isEmpty(list),"重复数据");

            List<RoleAreaUser> roleAreaUsers = roleAreaUserService.lambdaQuery().eq(RoleAreaUser::getRoleAreaId, roleArea.getId()).list();

            roleAreaUserService.removeByIds(roleAreaUsers.stream().map(e->e.getId()).collect(Collectors.toList()));

        }


        if(CollectionUtil.isNotEmpty(input.getUserId())){
            for (Long userId : input.getUserId()) {
                RoleAreaUser roleAreaUser = new RoleAreaUser();
                roleAreaUser.setRoleAreaId(roleArea.getId());
                roleAreaUser.setUserId(userId);
                roleAreaUserService.save(roleAreaUser);
            }
        }
    }

    @Override
    public List<RoleAreaUserVo> listAll(RoleAreaQueryInput input){

        List<RoleAreaUserVo> result = new ArrayList<>();

        List<Role> roles = roleService.lambdaQuery().in(CollectionUtil.isNotEmpty(input.getRoleName()),Role::getRoleName,input.getRoleName()).list();

        List<RoleArea> roleAreas = lambdaQuery()
                .eq(StringUtils.isNotEmpty(input.getErea()),RoleArea::getArea,input.getErea())
                .in(CollectionUtil.isNotEmpty(roles),RoleArea::getRoleId,roles.stream().map(e->e.getId()).collect(Collectors.toList()))
                .orderByAsc(RoleArea::getRoleId).list();

        for (RoleArea roleArea : roleAreas) {

            RoleAreaUserVo vo = new RoleAreaUserVo();

            vo.setId(roleArea.getId());

            vo.setArea(roleArea.getArea());

            Role role = roleService.lambdaQuery().eq(Role::getId,roleArea.getRoleId()).one();

            if(role !=null) {
                vo.setRoleName(role.getRoleName());
                vo.setRoleId(role.getId());
            }

            List<Long> userIds = roleAreaUserService.lambdaQuery().eq(RoleAreaUser::getRoleAreaId,roleArea.getId())
                    .list().stream().map(e->e.getUserId()).collect(Collectors.toList());

            if(CollectionUtil.isNotEmpty(userIds)) {
                List<User> users = userService.lambdaQuery().in(User::getId, userIds).list();

                String userName = StringUtils.join(users.stream().map(e -> e.getUserName()).collect(Collectors.toList()), ",");

                vo.setUserId(userIds);

                vo.setUserNames(userName);
            }

            result.add(vo);
        }

        return result;
    }

    @Transactional
    @Override
    public void delete(Long id){
        List<RoleAreaUser> roleAreaUsers = roleAreaUserService.lambdaQuery().eq(RoleAreaUser::getRoleAreaId, id).list();
        if(CollectionUtil.isNotEmpty(roleAreaUsers)){
            roleAreaUserService.removeByIds(roleAreaUsers.stream().map(e->e.getId()).collect(Collectors.toList()));
        }
        //删除主表
        removeById(id);
    }

    /**
     * 根据辖区，票证类型获取人员对于辖区
     * @param input
     */
    @Override
    public List<String> getAreaByUser(GetAreaByUserInput input){

        List<String> result = new ArrayList<>();

        User user = userService.lambdaQuery().eq(User::getUserNum,input.getUserNum()).one();

        if(user == null) return result;

        Role role = roleService.lambdaQuery().eq(Role::getRoleNum,ROLE_NAME)
                .one();

        if(role == null) return result;
        //查出人员拥有的
        List<Long> roleAreaIds = roleAreaUserService.lambdaQuery()
                .eq(RoleAreaUser::getUserId, user.getId())
                .list()
                .stream().map(e -> e.getRoleAreaId())
                .collect(Collectors.toList());

        if(CollectionUtil.isEmpty(roleAreaIds)) return result;

        return lambdaQuery()
                .eq(RoleArea::getRoleId,role.getId())
                .in(RoleArea::getId,roleAreaIds).list()
                .stream().map(e->e.getArea())
                .collect(Collectors.toList());
    }
}
